Make boolean string parsing consistent, #452464
authorJohan Dahlin <jdahlin@async.com.br>
Sat, 30 Jun 2007 06:57:47 +0000 (06:57 +0000)
committerJohan Dahlin <johan@src.gnome.org>
Sat, 30 Jun 2007 06:57:47 +0000 (06:57 +0000)
2007-06-30  Johan Dahlin  <jdahlin@async.com.br>

    * gtk/gtkbuilder.c: (gtk_builder_value_from_string_type):
    * gtk/gtkbuilderparser.c: (_gtk_builder_parse_boolean),
    (parse_property), (parse_signal):
    * gtk/gtkbuilderprivate.h:
    * tests/buildertest.c: (test_value_from_string):
    Make boolean string parsing consistent, #452464

svn path=/trunk/; revision=18305

ChangeLog
gtk/gtkbuilder.c
gtk/gtkbuilderparser.c
gtk/gtkbuilderprivate.h
tests/buildertest.c

index 440968f34cbdb064088a33cf61fbf3ff005cb067..504334ed8f3e0cfe57fe33ad1086263133de914e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-06-30  Johan Dahlin  <jdahlin@async.com.br>
+
+       * gtk/gtkbuilder.c: (gtk_builder_value_from_string_type):
+       * gtk/gtkbuilderparser.c: (_gtk_builder_parse_boolean),
+       (parse_property), (parse_signal):
+       * gtk/gtkbuilderprivate.h:
+       * tests/buildertest.c: (test_value_from_string):
+       Make boolean string parsing consistent, #452464
+
 2007-06-30  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkbuilder.c:
index 03f28817eabd9a4d6e48652492c8e2f97bc7e83c..22228acdc19863c205fcfd1057ed8dab7c4c1254 100644 (file)
@@ -1038,33 +1038,10 @@ gtk_builder_value_from_string_type (GtkBuilder   *builder,
       {
         gboolean b;
 
-        switch (g_ascii_tolower (string[0]))
-          {
-          case 't':
-          case 'y':
-            b = TRUE;
-            break;
-          case 'f':
-          case 'n':
-            b = FALSE;
-            break;
-          default:
-            {
-              gchar *endptr;
-              errno = 0;
-              b = strtol (string, &endptr, 0);
-              if (errno || endptr == string)
-                {
-                 g_set_error (error,
-                              GTK_BUILDER_ERROR,
-                              GTK_BUILDER_ERROR_INVALID_VALUE,
-                              "Could not parse boolean `%s'",
-                              string);
-                  ret = FALSE;
-                  break;
-                }
-            }
-            break;
+       if (!_gtk_builder_parse_boolean (string, &b, error))
+         {
+           ret = FALSE;
+           break;
           }
         g_value_set_boolean (value, b);
         break;
index a619a1f5072b53a46a95b4c847c1c78cb6b5c8f7..a18d5ec7c4c8667ad2d9ff02dc8838975f8f80c6 100644 (file)
@@ -157,6 +157,55 @@ error_missing_property_value (ParserData *data,
               line_number, char_number);
 }
 
+gboolean
+_gtk_builder_parse_boolean (const gchar  *string,
+                           gboolean     *value,
+                           GError      **error)
+{
+  gboolean retval = TRUE;
+  int i;
+  int length;
+  
+  g_assert (string != NULL);
+  length = strlen (string);
+  
+  if (length == 0)
+    retval = FALSE;
+  else if (length == 1)
+    {
+      gchar c = g_ascii_tolower (string[0]);
+      if (c == 'y' || c == 't' || c == '1')
+       *value = TRUE;
+      else if (c == 'n' || c == 'f' || c == '0')
+       *value = FALSE;
+      else
+       retval = FALSE;
+    }
+  else
+    {
+      gchar *lower = g_strdup (string);
+      for (i = 0; i < strlen (string); i++)
+       lower[i] = g_ascii_tolower (string[i]);
+      
+      if (strcmp (lower, "yes") == 0 || strcmp (lower, "true") == 0)
+       *value = TRUE;
+      else if (strcmp (lower, "no") == 0 || strcmp (lower, "false") == 0)
+       *value = FALSE;
+      else
+       retval = FALSE;
+      g_free (lower);
+    }
+  
+  if (!retval)
+    g_set_error (error,
+                GTK_BUILDER_ERROR,
+                GTK_BUILDER_ERROR_INVALID_VALUE,
+                "could not parse boolean `%s'",
+                string);
+
+  return retval;
+}
+
 static GObject *
 builder_construct (ParserData *data,
                    ObjectInfo *object_info)
@@ -353,7 +402,10 @@ parse_property (ParserData   *data,
       if (strcmp (names[i], "name") == 0)
         name = g_strdelimit (g_strdup (values[i]), "_", '-');
       else if (strcmp (names[i], "translatable") == 0)
-        translatable = strcmp (values[i], "yes") == 0;
+       {
+         if (!_gtk_builder_parse_boolean (values[i], &translatable, error))
+           return;
+       }
       else
        {
          error_invalid_attribute (data, element_name, names[i], error);
@@ -408,10 +460,14 @@ parse_signal (ParserData   *data,
       else if (strcmp (names[i], "handler") == 0)
         handler = g_strdup (values[i]);
       else if (strcmp (names[i], "after") == 0)
-        after = strcmp (values[i], "yes") == 0;
+       {
+         if (!_gtk_builder_parse_boolean (values[i], &after, error))
+           return;
+       }
       else if (strcmp (names[i], "swapped") == 0)
        {
-         swapped = strcmp (values[i], "yes") == 0;
+         if (!_gtk_builder_parse_boolean (values[i], &swapped, error))
+           return;
          swapped_set = TRUE;
        }
       else if (strcmp (names[i], "object") == 0)
index 1a65d48cc4475aaf87d92b28c3001ebd9894ecfa..11d8974a77d48c46c37580c100cc96ddded9e1a9 100644 (file)
@@ -107,5 +107,8 @@ void      _gtk_builder_add (GtkBuilder *builder,
 void      _gtk_builder_finish (GtkBuilder *builder);
 void _free_signal_info (SignalInfo *info,
                         gpointer user_data);
+gboolean _gtk_builder_parse_boolean (const gchar  *string,
+                                    gboolean     *value,
+                                    GError      **error);
 
 #endif /* __GTK_BUILDER_PRIVATE_H__ */
index ce46928968c93c6e663403b3956e653e0a4f9005..48fbd88cee6d41b2d0a159d4e2b8e4edb5d65f74 100644 (file)
@@ -1508,6 +1508,11 @@ test_value_from_string (void)
   g_return_val_if_fail (g_value_get_boolean (&value) == TRUE, FALSE);
   g_value_unset (&value);
 
+  g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "tRuE", &value, &error), FALSE);
+  g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE);
+  g_return_val_if_fail (g_value_get_boolean (&value) == TRUE, FALSE);
+  g_value_unset (&value);
+  
   g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "blaurgh", &value, &error) == FALSE, FALSE);
   g_return_val_if_fail (error != NULL, FALSE);
   g_value_unset (&value);
@@ -1516,6 +1521,27 @@ test_value_from_string (void)
   g_error_free (error);
   error = NULL;
 
+  g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yess", &value, &error) == FALSE, FALSE);
+  g_value_unset (&value);
+  g_return_val_if_fail (error->domain == GTK_BUILDER_ERROR, FALSE);
+  g_return_val_if_fail (error->code == GTK_BUILDER_ERROR_INVALID_VALUE, FALSE);
+  g_error_free (error);
+  error = NULL;
+  
+  g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "trueee", &value, &error) == FALSE, FALSE);
+  g_value_unset (&value);
+  g_return_val_if_fail (error->domain == GTK_BUILDER_ERROR, FALSE);
+  g_return_val_if_fail (error->code == GTK_BUILDER_ERROR_INVALID_VALUE, FALSE);
+  g_error_free (error);
+  error = NULL;
+  
+  g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "", &value, &error) == FALSE, FALSE);
+  g_value_unset (&value);
+  g_return_val_if_fail (error->domain == GTK_BUILDER_ERROR, FALSE);
+  g_return_val_if_fail (error->code == GTK_BUILDER_ERROR_INVALID_VALUE, FALSE);
+  g_error_free (error);
+  error = NULL;
+  
   g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "12345", &value, &error), FALSE);
   g_return_val_if_fail (G_VALUE_HOLDS_INT (&value), FALSE);
   g_return_val_if_fail (g_value_get_int (&value) == 12345, FALSE);